package com.boge.util.myutils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class SftpClientTool {
	/** Sftp */
	private ChannelSftp sftp = null;
	/** 主机 */
	private String host = "";
	/** 端口 */
	private int port = 22;
	/** 用户名 */
	private String username = "";
	/** 密码 */
	private String password = "";

	/**
	 * 构造函数
	 * 
	 * @param host
	 *            主机
	 * @param port
	 *            端口
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * 
	 */
	public SftpClientTool(String host, int port, String username,
			String password) {
		this.host = host;
		this.port = port;
		this.username = username;
		this.password = password;
	}

	/**
	 * 构造函数
	 * 
	 * @param host
	 *            主机
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * 
	 */
	public SftpClientTool(String host, String username, String password) {
		this.host = host;
		this.username = username;
		this.password = password;
	}

	/**
	 * 连接sftp服务器，默认超时时间20000
	 * 
	 * @throws Exception
	 */
	public void connect() throws Exception {
		connect(20000);
	}

	/**
	 * 连接sftp服务器
	 * 
	 * @param timeout
	 *            超时时间
	 * 
	 * @throws Exception
	 */
	public void connect(int timeout) throws Exception {
		JSch jsch = new JSch();
		Session sshSession = jsch.getSession(this.username, this.host,
				this.port);
		sshSession.setPassword(password);
		Properties sshConfig = new Properties();
		sshConfig.put("StrictHostKeyChecking", "no");
		sshSession.setConfig(sshConfig);
		sshSession.connect(timeout);
		Channel channel = sshSession.openChannel("sftp");
		channel.connect();
		this.sftp = (ChannelSftp) channel;
	}

	/**
	 * 断开sftp服务器连接
	 * 
	 * @throws Exception
	 */
	public void disconnect() throws Exception {
		if (this.sftp != null) {
			if (this.sftp.isConnected()) {
				this.sftp.disconnect();
			} else if (this.sftp.isClosed()) {
			}
			this.sftp = null;
		}
	}

	/**
	 * 上传单个文件
	 * 
	 * @param directory
	 *            上传的目录
	 * @param uploadFile
	 *            要上传的文件
	 * 
	 * @throws Exception
	 */
	public void upload(String directory, String uploadFile) throws Exception {
		this.sftp.cd(directory);
		File file = new File(uploadFile);
		// 如果文件夹不存在，创建之
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		this.sftp.put(new FileInputStream(file), file.getName());
	}

	/**
	 * 下载单个文件
	 * 
	 * @param directory
	 *            下载目录
	 * @param downloadFile
	 *            下载的文件
	 * @param saveFile
	 *            保存文件
	 * 
	 * @throws Exception
	 */
	public void download(String directory, String downloadFile, String saveFile)
			throws Exception {
		this.sftp.cd(directory);
		File file = new File(saveFile);
		// 如果文件夹不存在，创建之
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		this.sftp.get(downloadFile, new FileOutputStream(file));
	}

	/**
	 * 删除文件
	 * 
	 * @param directory
	 *            要删除文件所在目录
	 * @param deleteFile
	 *            要删除的文件
	 * 
	 * @throws Exception
	 */
	public void delete(String directory, String deleteFile) throws Exception {
		this.sftp.cd(directory);
		this.sftp.rm(deleteFile);
	}

	/**
	 * 列出目录下的文件
	 * 
	 * @param directory
	 *            要列出的目录
	 * 
	 * @return list 文件名列表
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public List<String> listFiles(String directory) throws Exception {
		List<String> fileNameList = new ArrayList<String>();
		Vector<LsEntry> fileList = this.sftp.ls(directory);
		Iterator<LsEntry> it = fileList.iterator();
		while (it.hasNext()) {
			String fileName = it.next().getFilename();
			// 特殊文件名，忽略
			if (".".equals(fileName) || "..".equals(fileName)) {
				continue;
			}
			fileNameList.add(fileName);
		}
		return fileNameList;
	}

	/**
	 * 更改文件名
	 * 
	 * @param directory
	 *            文件所在目录
	 * @param oldFileNm
	 *            原文件名
	 * @param newFileNm
	 *            新文件名
	 * 
	 * @throws Exception
	 */
	public void rename(String directory, String oldFileNm, String newFileNm)
			throws Exception {
		this.sftp.cd(directory);
		this.sftp.rename(oldFileNm, newFileNm);
	}
}